package com.ttdevs.util;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Locale;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Environment;
import android.text.TextUtils;

public class Utils {
	/** 应用的根目录 */
	public static final String ROOT_DIRECTORY = "/ImageCache/";

	/** 获取默认目录 */
	public static String getImageCacheDir() {
		return Environment.getExternalStorageDirectory() + ROOT_DIRECTORY;
	}

	/** 获取默认外部私有图片目录 */
	public static String getExternalPrivateDirOfPicture(Context context) {
		return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getPath();
	}

	/** Checks if external storage is available for read and write */
	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	/** Checks if external storage is available to at least read */
	public static boolean isExternalStorageReadable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			return true;
		}
		return false;
	}

	/**
	 * 根据传入的url，生成指定的文件名。 <br>
	 * 
	 * @param url
	 *            Volley中生成的文件路径，{@link getCacheKey}，如：<br>
	 *            #W100#H100https://lh6.googleusercontent.com/Photographer.jpg
	 * @return 生成的文件名，规则：#W100#H100_Photographer.jpg
	 */
	public static String getVolleyRuleFileName(String url) {
		StringBuffer sb = new StringBuffer();
		if (!TextUtils.isEmpty(url)) {
			url = url.toLowerCase(Locale.US);// 全部小写
			int index = url.indexOf("http");
			if (index == -1) {
				return null;
			}
			sb.append(url.substring(0, index));
			sb.append("_");
			sb.append(url.substring(url.lastIndexOf("/") + 1, url.length()));
		}
		return sb.toString();
	}

	/**
	 * 获得设置信息 BitmapFactory这个类提供了多个解析方法(decodeByteArray, decodeFile,
	 * decodeResource等
	 * )用于创建Bitmap对象，我们应该根据图片的来源选择合适的方法。比如SD卡中的图片可以使用decodeFile方法，
	 * 网络上的图片可以使用decodeStream方法
	 * ，资源文件中的图片可以使用decodeResource方法。这些方法会尝试为已经构建的bitmap分配内存
	 * ，这时就会很容易导致OOM出现。为此每一种解析方法都提供了一个可选的BitmapFactory
	 * .Options参数，将这个参数的inJustDecodeBounds属性设置为true就可以让解析方法禁止为bitmap分配内存
	 * ，返回值也不再是一个Bitmap对象
	 * ，而是null。虽然Bitmap是null了，但是BitmapFactory.Options的outWidth、
	 * outHeight和outMimeType属性都会被赋值
	 * 。这个技巧让我们可以在加载图片之前就获取到图片的长宽值和MIME类型，从而根据情况对图片进行压缩。 <br>
	 * int imageHeight = options.outHeight; <br>
	 * int imageWidth = options.outWidth; <br>
	 * String imageType = options.outMimeType; // MimeType
	 */
	public static Options getOptions(String path) {
		Options options = new Options();
		options.inJustDecodeBounds = true;// 只描边，不读取数据
		BitmapFactory.decodeFile(path, options);
		return options;
	}

	/**
	 * 那我们怎样才能对图片进行压缩呢？通过设置BitmapFactory.Options中inSampleSize的值就可以实现。比如我们有一张2048
	 * *1536像素的图片，将inSampleSize的值设置为4，就可以把这张图片压缩成512*384像素。原本加载这张图片需要占用13M的内存，
	 * 压缩后就只需要占用0 .75M了(假设图片是ARGB_8888类型，即每个像素点占用4个字节)。下面的方法可以根据传入的宽和高，
	 * 计算出合适的inSampleSize值
	 * 
	 * @param options
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
		// 源图片的高度和宽度
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;
		if (height > reqHeight || width > reqWidth) {
			// 计算出实际宽高和目标宽高的比率
			final int heightRatio = Math.round((float) height / (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);
			// 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
			// 一定都会大于等于目标的宽和高。
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}
		return inSampleSize;
	}

	/**
	 * 首先你要将BitmapFactory.Options的inJustDecodeBounds属性设置为true，解析一次图片。
	 * 然后将BitmapFactory
	 * .Options连同期望的宽度和高度一起传递到到calculateInSampleSize方法中，就可以得到合适的inSampleSize值了
	 * 。之后再解析一次图片，使用新获取到的inSampleSize值，并把inJustDecodeBounds设置为false，就可以得到压缩后的图片了
	 * 
	 * @param res
	 *            The resources object containing the image data
	 * @param resId
	 *            The resource id of the image data
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
		// 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeResource(res, resId, options);
		// 调用上面定义的方法计算inSampleSize值
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
		// 使用获取到的inSampleSize值再次解析图片
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeResource(res, resId, options);
	}

	/**
	 * 从文件加载图片
	 * 
	 * @param path
	 * @param reqWidth
	 * @param reqHeight
	 * @return
	 */
	public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) {
		// 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
		final BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, options);
		// 调用上面定义的方法计算inSampleSize值
		options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
		// 使用获取到的inSampleSize值再次解析图片
		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}

	public static Bitmap scaleBitmap(Bitmap bitmap, int width, int dia) {
		float scale = (float) (dia / (width * 1.0));
		Matrix matrix = new Matrix();
		matrix.postScale(scale, scale); // 长和宽放大缩小的比例
		Bitmap resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, width,
				width < bitmap.getHeight() ? width : bitmap.getHeight(), matrix, true);
		return resizeBmp;
	}

	public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int dia) {
		Bitmap outBitmap = Bitmap.createBitmap(dia, dia, Config.ARGB_8888);
		Canvas canvas = new Canvas(outBitmap);
		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, dia, dia);
		final RectF rectF = new RectF(rect);
		final float roundPX = bitmap.getWidth() / 2;
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPX, roundPX, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);
		return outBitmap;
	}

	/**
	 * 保存Bitmap对象为本地图片
	 * 
	 * @param dir
	 *            要保存的目标文件路径
	 * @param key
	 *            文件名
	 * @param bmp
	 *            Bitmap对象
	 * @return
	 */
	public static boolean saveBitmap2file(String dir, String key, Bitmap bmp) {
		boolean isSuccess = false;
		if (dir == null || key == null || bmp == null) {
			return isSuccess;
		}

		FileOutputStream out = null;
		try {
			out = new FileOutputStream(new File(dir, getVolleyRuleFileName(key)));
			isSuccess = bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			return isSuccess;
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return isSuccess;
	}

	/**
	 * 来自：Volley>>com.android.volley.toolbox.ImageLoader<br>
	 * 
	 * @param url
	 *            图片的url
	 * @param maxWidth
	 *            图片的最大宽
	 * @param maxHeight
	 *            图片的最大高
	 * @return
	 */
	public static String getCacheKey(String url, int maxWidth, int maxHeight) {
		return new StringBuilder(url.length() + 12).append("#W").append(maxWidth).append("#H").append(maxHeight)
				.append(url).toString();
	}
}
